<!--
 * @Author: 赵宇
 * @Description: 
 * @Date: 2024-01-27 13:37:55
 * @LastEditTime: 2025-02-17 22:26:15
 * @LastEditors: zhao 13370229059@163.com
 * @FilePath: \dance\pages\main\course.vue
-->
<template>
  <view class="course" v-if="JSON.stringify(rData) !== '{}'">
    <!-- 头部 -->
    <uv-status-bar bgColor="#000"></uv-status-bar>
    <view class="course-navbar">
      <!--自定义头部 -->
      <zy-navbar></zy-navbar>
    </view>
    <!-- 视频 -->
    <view class="course-content" :style="{ height: rData.offline === 1 || rData.classify === 'MerchantLesson' ? '1213.953rpx' : '422.093rpx' }">
      <!-- 如果当前视频地址是个图片，就直接展示一张图片 -->
      <template v-if="isFileType(rData.video.address) === 'image'">
        <uv-image :src="rData.video.address" height="100%" width="100%"></uv-image>
      </template>
      <!-- 如果当前地址是个视频，就播放视频 -->
      <template v-else-if="isFileType(rData.video.address) === 'video'">
        <m-video
          autoplay
          loop
          show-speed-rate-btn
          show-casting-button
          show-mute-btn
          controls
          :src="rData.video.address"
          object-fit="cover"
          token="AsMqnVHVX5siSwwz4ckDCOCHCim5XsvNNXR1GkIVmrs="
          @ended="tally('play')"
        />
      </template>
      <!-- 如果当前地址是个音频-->
      <template v-else-if="isFileType(rData.video.address) === 'mp3'">
        <uv-image :src="rData.video.cover || defaultImagesList[random]" height="100%" width="100%"></uv-image>
      </template>
      <!-- 如果当前视频地址是空，或者既不是视频，也不是图片 就只是展示个封面 -->
      <template v-else-if="!rData.video.address || isFileType(rData.video.address) === 'unknown'">
        <uv-image :src="rData.video.cover || defaultImagesList[random]" height="100%" width="100%"></uv-image>
      </template>
      <!-- 如果是个音乐 -->
      <view class="course-content-audio" v-if="isFileType(rData.video.address) === 'mp3'">
        <uv-icon :name="audioState ? 'pause' : 'play-right'" color="#fff" size="28" @click="onAudio"></uv-icon>
      </view>
      <!-- <view class="course-content-sign"></view> -->
    </view>
    <view class="course-info">
      <view class="buttons">
        <uv-line direction="col" color="#b1b1b1" length="34.884rpx"></uv-line>
        <view class="buttons-item buttons-share">
          <button open-type="share" class="reset-button course-info-icon">分享</button>
        </view>
        <uv-line direction="col" color="#b1b1b1" length="34.884rpx"></uv-line>
        <view class="buttons-item" @click.stop="httpCollect(item)">
          <button class="reset-button course-info-icon">{{ rData.collected.id === 0 ? '+收藏' : '已收藏' }}</button>
        </view>
      </view>
    </view>
    <!-- 舞蹈服信息 -->
    <view class="course-name">
      <view class="course-name-title">
        <view class="label">{{ rData.lesson.name }}</view>
      </view>
      <view class="subtitle">
        <view class="dance">
          {{ rData.lesson.danceType }}
        </view>
        <view class="buy">
          <text class="buy-label">剩余名额</text>
          <text>{{ rData.lesson.traineeCount - rData.purchased }}</text>
        </view>
      </view>
    </view>
    <view class="course-time">
      <template v-if="Number(rData.lesson.personage) === 1">
        <view
          class="course-time-info"
          v-for="(row, index) in rData.issues"
          :style="{ marginBottom: index + 1 === rData.issues.length ? 0 : '24rpx' }"
        >
          <view class="time">{{ row.timeDuration }}</view>
          <view>{{ row.classTime }}&nbsp;&nbsp;{{ row.week }}</view>
        </view>
      </template>
      <template v-else>
        <view class="course-time-info">
          <view class="time">{{ rData.timeDuration }}</view>
          <view>{{ rData.issueDate }}&nbsp;&nbsp;{{ rData.week }}</view>
        </view>
      </template>
    </view>
    <view v-if="percentage">
      <uv-line-progress :percentage="percentage"></uv-line-progress>
    </view>
    <!-- 舞房信息和时间 -->
    <view class="course-tips">
      <view class="course-tips-avatar" @click="onGoMerchant(rData.merchant.id)">
        <uv-avatar :src="rData.merchant.licenses[0]?.imgPath || defaultImages[3]" size="95.93rpx" mode="aspectFill"></uv-avatar>
        <view class="add" @click.stop="onCollect(rData.merchant, 'merchant')" v-if="!rData.merchant.collected.id"> + </view>
      </view>

      <uv-line direction="col" color="#5e5e5e" margin="0 20.93rpx" length="auto"></uv-line>
      <view class="course-tips-info">
        <view class="name">
          {{ rData.merchant.headquater.name }}
          <view class="name-sub">
            {{ rData.merchant.name }}
          </view>
        </view>
        <view class="location">{{ rData.location.province }}{{ rData.location.district }}{{ rData.location.detail }}</view>
      </view>
      <view class="course-tips-icon" @click.stop="goLocation">
        <uv-icon name="dingwei" custom-prefix="custom-icon" color="#FF7A66" size="52rpx"></uv-icon>
      </view>
    </view>
    <view class="course-line">
      <uv-line color="#5e5e5e" margin="48.837rpx 0"></uv-line>
    </view>
    <!--  老师信息-->
    <view class="course-tips">
      <view class="course-tips-avatar">
        <uv-avatar
          :src="rData.teacher.profilePhoto || defaultImages[3]"
          size="95.93rpx"
          mode="aspectFill"
          @click="onGoTeacher(rData.teacher.id)"
        ></uv-avatar>
        <view class="add" @click.stop="onCollect(rData.teacher, 'teacher')" v-if="!rData.teacher.collected.id"> + </view>
      </view>
      <uv-line direction="col" color="#5e5e5e" margin="0 20.93rpx" length="auto"></uv-line>
      <view class="course-tips-info">
        <view class="name">{{ rData.teacher.username }}</view>
        <view class="location">{{ rData.teacher.description }}</view>
      </view>
    </view>
    <view class="course-line">
      <uv-line color="#5e5e5e" margin="48.837rpx 0 55.814rpx 0"></uv-line>
    </view>
    <!-- 课程内容 -->
    <view class="course-introduce">
      <view class="course-introduce-title">课程介绍</view>
      <view class="course-introduce-grade">
        课程难度：
        <view class="grade">{{ gradeOptions.find(r => r.val === rData.lesson.grade).label }}</view>
      </view>
      <view class="course-introduce-content">
        <view v-html="rData.descriptionContent || rData.lesson.abstract"></view>
      </view>
      <view class="course-introduce-progress" v-if="rData.offline === 2">
        课程进度：
        <view class="progress">
          <view class="label">总课时{{ rData.lesson.allCourse || 0 }}节</view>
          <view>当前课程第{{ rData.lesson.currentCourse || 0 }}节</view>
        </view>
      </view>
    </view>
    <view class="course-line">
      <uv-line color="#5e5e5e" margin="76.744rpx 0 55.814rpx 0"></uv-line>
    </view>

    <view class="course-care">
      <view class="course-care-title">注意事项</view>
      <view class="course-care-content">
        <view class="item">
          <view class="yuan"> </view>
          购买课程后，会生成一个二维码，请在门店扫描二维码核销后才能进入教室上课；
        </view>
        <view class="item">
          <view class="yuan"> </view
          >不适宜人群：孕妇、产妇（顺产后不足6个月，剖腹产后不足1年）、心血管疾病患者以及其他医生不建议参与剧烈锻炼的伤病患者不得参加课程;
        </view>
      </view>
    </view>
    <view class="course-line">
      <uv-line color="#5e5e5e" margin="76.744rpx 0 55.814rpx 0"></uv-line>
    </view>

    <!-- <view class="course-care">
      <view class="course-care-title">退款规则</view>
      <view class="course-care-content">
        <view class="item">
          <view class="yuan"> </view>
          无法参加课程时，请在课程开始前至少2小时联系客服申请退款。
        </view>
        <view class="item"> <view class="yuan"> </view>开课前2小时内将无法退款，购买时需要谨慎考虑； </view>
        <view class="item"> <view class="yuan"> </view>如果老师因突发情况无法上课，课程取消后，客服会负责操作退款 </view>
      </view>
    </view> 
    <view class="course-line">
      <uv-line color="#5e5e5e" margin="76.744rpx 0 0 0"></uv-line>
    </view> -->
  </view>
  <view class="float-wrapper">
    <view class="float-wrapper_txt">
      <text class="float-wrapper_txt-decimal">￥</text>
      <text>{{ rData.inter }}</text>
      <text class="float-wrapper_txt-decimal">.{{ rData.decimal }}</text>
    </view>
    <uv-button
      class="float-wrapper_pay"
      text="支付"
      :customStyle="{
        backgroundColor: '#FF7A66',
        color: '#fff',
        border: 'none',
        height: '100%',
        'border-top-left-radius': '0',
        'border-top-right-radius': '21rpx',
        'border-bottom-left-radius': '0',
        'border-bottom-right-radius': '21rpx'
      }"
      :customTextStyle="{
        fontSize: '34.884rpx',
        fontWeight: 700,
        height: '100%',
        display: 'flex',
        alignItems: 'center',
        width: '226.744rpx',
        justifyContent: 'center'
      }"
      @click="onGetuserinfo"
      size="large"
    ></uv-button>
  </view>
  <uv-safe-bottom></uv-safe-bottom>
  <uv-toast ref="toastRef"></uv-toast>
</template>
<script setup>
  import { defaultImages, defaultImagesList, gradeOptions, shareList } from '@/common/js/global.js';
  import store from '@/store/index.js'; //需要引入store
  let { state, commit } = store;
  import { onLoad, onHide, onReady, onShow, onUnload, onShareTimeline, onShareAppMessage } from '@dcloudio/uni-app';
  import { reactive, ref, computed } from 'vue';
  import { onHome, onLeft, login, isFileType, getGradeToWho, isTimeNull, getWeek, onGoTeacher } from '@/common/js/fn';
  import dayjs from '@/uni_modules/uv-ui-tools/libs/util/dayjs.js';
  import weekday from '@/common/js/weekday.js';
  import { suiji } from '@/common/js/fn.js';
  dayjs.extend(weekday);
  let random = ref(0);

  const toastRef = ref();
  let ajaxData = reactive({
    data: {}
  });
  let rData = computed(() => {
    return ajaxData.data;
  });
  let routerVal = reactive({
    id: undefined
  });

  // 音频
  let innerAudioContext = '';
  let audioState = ref(true);
  // 远程请求课程详情
  let httpDetail = async () => {
    random.value = await suiji(0, defaultImagesList.length - 1);
    let data = await uni.$uv.http.post('app/lesson/show', {
      id: routerVal.id
    });
    let { lesson, issues = [] } = data;
    // 价格除以100
    let arr = Number(lesson.price / 100)
      .toFixed(2)
      .toString()
      .split('.');
    if (issues.length) {
      issues = issues.map(r => {
        let classTime = dayjs(r.classTime).format('MM月-DD日');
        return {
          ...r,
          classTime,
          week: getWeek(r.classTime)
        };
      });
    } else {
      issues = [
        {
          classTime: dayjs(data.startDate).format('MM月-DD日'),
          timeDuration: data.timeDuration,
          week: getWeek(data.startDate)
        }
      ];
    }
    let title = data.lesson.shareTitle;
    if (!title) {
      let random = await suiji(0, shareList.length - 1);
      title = shareList[random].name;
    }
    title += `#${data.lesson.name}，快来一起跳舞吧~`;
    // 去卡转发的视频，名字是当前课程名称
    let imageUrl = data.forwardCover || data.video.cover;
    ajaxData.data = {
      ...data,
      issueDate: dayjs(data.issueDate).format('M月DD日'),
      location: data.lesson.personage === 1 ? {} : data.lesson?.merchant?.location,
      week: !isTimeNull(data.issueDate) ? getWeek(data.issueDate) : '',
      price: Number(lesson.price / 100).toFixed(2),
      inter: arr[0],
      decimal: arr[1],
      attention: data.attention.replace(/\n/g, '<br/>'),
      descriptionContent: data.description?.content.replace(/\n/g, '<br/>'),
      merchant: data.lesson.merchant,
      teacher: data.lesson.teacher,
      issues,
      title,
      imageUrl
    };
    if (isFileType(rData.value.video?.address) === 'mp3') {
      innerAudioContext = uni.createInnerAudioContext();
      innerAudioContext.src = rData.value.video.address;
      innerAudioContext.autoplay = true;
    }
    tally('click');
  };
  onShow(() => {});
  // 销毁音频事件
  let audioDestroy = () => {
    if (!innerAudioContext) return;
    innerAudioContext.pause();
  };
  // 音乐是否播放
  let onAudio = () => {
    innerAudioContext[audioState.value ? 'pause' : 'play']();
    audioState.value = !audioState.value;
  };
  // 到下级页面是消失事件
  onHide(() => {
    audioDestroy();
  });
  // 到主页就是销毁事件 二个都要调用销毁方法
  onUnload(() => {
    audioDestroy();
  });
  let httpCollect = async () => {
    await uni.$uv.http.post(`app/collect/${!ajaxData.data.collected.id ? 'add' : 'cancel'}`, {
      classify: 'Lesson', //收藏类型
      objid: ajaxData.data.id, //收藏对象的数据ID
      optype: 'collect' //操作类型
    });
    ajaxData.data.collected.id = ajaxData.data.collected.id ? 0 : 1;
    toastRef.value.show({
      overlay: false,
      message: `${ajaxData.data.collected.id ? '' : '取消'}收藏成功`,
      type: 'success'
    });
  };
  const onCollect = async (val, type) => {
    await uni.$uv.http.post(`app/collect/add`, {
      classify: type, //收藏类型
      objid: val.id, //收藏对象的数据ID
      optype: 'collect' //操作类型
    });
    val.collected.id = 1;
    toastRef.value.show({
      overlay: false,
      message: `收藏成功`,
      type: 'success'
    });
  };
  // 获取远程数据
  onLoad(async option => {
    routerVal.id = Number(option.id);
    httpDetail();
  });
  // 支付跳转
  const onGetuserinfo = detail => {
    if (rData.value.purchased >= rData.value.lesson.traineeCount) {
      toastRef.value.show({
        overlay: false,
        message: '该课程已满员',
        type: 'error'
      });
      return;
    }
    uni.$uv.route({
      url: '/pages/pay/pay',
      params: {
        id: routerVal.id
      }
    });
  };

  const goLocation = () => {
    let { lesson } = ajaxData.data;
    let { location } = ajaxData.data.merchant;
    let isTeacherPush = Number(lesson.personage) === 1;
    let latitude = isTeacherPush ? lesson.latitude : location.latitude;
    let longitude = isTeacherPush ? lesson.logitude : location.logitude;
    let name = isTeacherPush ? lesson.province : location.city;
    let address = isTeacherPush ? lesson.district + lesson.detail : location.district + location.detail;
    uni.openLocation({
      latitude, // 上海的纬度
      longitude, // 上海的经度
      name, // 地点名称
      address, // 地址的详细说明
      scale: 18, // 缩放比例
      success: function (res) {},
      fail: function (err) {}
    });
  };
  // 下载视频
  let percentage = ref(0);
  let downloadFile = async () => {
    // 先检查有没有打开保存视频的功能
    uni.authorize({
      scope: 'scope.writePhotosAlbum',
      success() {
        // 如果已经是打开的，直接下载视频
        const downloadTask = uni.downloadFile({
          url: ajaxData.data.video.address,
          success: res => {
            // 下载成功之后保存视频
            uni.saveVideoToPhotosAlbum({
              filePath: res.tempFilePath,
              success: () => {
                toastRef.value.show({
                  overlay: false,
                  message: `下载成功`,
                  type: 'success'
                });
              },
              fail: val => {}
            });
          },
          fail: val => {}
        });
        downloadTask.onProgressUpdate(res => {
          percentage.value = Number(res.progress);
          if (percentage.value < 20) {
            toastRef.value.show({
              overlay: false,
              message: `下载中`,
              type: 'info'
            });
          }
          if (percentage.value === 100) percentage.value = 0;
        });
      },
      fail: val => {
        toastRef.value.show({
          overlay: false,
          duration: 5000,
          message: `请在右上角 打开设置，开启添加到相册`,
          type: 'error'
        });
      }
    });
  };
  onReady(() => {});
  onShareTimeline(() => {
    let pages = uni.$uv.pages();
    let url = pages[pages.length - 1]?.$page?.fullPath || '';
    tally('share');
    return {
      title: rData.value.title,
      query: `${url.split('?')[1]}`,
      imageUrl: rData.value.imageUrl
    };
  });
  onShareAppMessage(() => {
    let pages = uni.$uv.pages();
    let url = pages[pages.length - 1]?.$page?.fullPath || '';
    let path = `${url}${url.includes('?') ? '&' : '?'}${url.includes('isShare') ? '' : 'isShare=1'}`;
    tally('share');
    return {
      title: rData.value.title,
      imageUrl: rData.value.imageUrl,
      path
    };
  });
  const onGoDancingRoom = val => {
    uni.$uv.route({
      url: '/pages/dancingRoom/dancingRoom',
      params: {
        id: rData.value.merchant.id
      }
    });
  };
  const onGoMerchant = id => {
    uni.$uv.route({
      url: '/pages/dancingRoom/dancingRoom',
      params: {
        id
      }
    });
  };
  const tally = async val => {
    await uni.$uv.http.post(
      'app/collect/statistic',
      {
        objectableID: rData.value.id,
        objectableType: rData.value.classify,
        operationType: val //render 展示 click 查看 share 分享 play 播放完
      },
      {
        custom: { toast: false }
      }
    );
  };
</script>

<style scoped>
  .flex-dir-column {
    flex-direction: column;
  }
  .ali-item-center {
    align-items: center;
  }
  .just-cont-spbetween {
    justify-content: space-between;
  }
  .tips {
    font-size: 24rpx;
    color: #b1b1b1;
  }
  .f-20 {
    color: #fff;
    font-size: 35rpx;
  }
</style>

<style scoped lang="scss">
  .course {
    font-family: Source Han Sans CN;
    background-color: #000;
    color: #fff;
    width: 100%;
    padding-bottom: 245.93rpx;

    &-content {
      width: 100%;
      position: relative;
      &-audio {
        width: 100%;
        padding: 0 20rpx;
        position: absolute;
        bottom: 20rpx;
        z-index: 999;
        color: #fff;
      }
      &-sign {
        position: absolute;
        height: 24rpx;
        width: 279rpx;
        background-color: #ff7a66;
        border-radius: 30rpx;
        bottom: -12rpx;
        left: 50%;
        transform: translateX(-50%);
        z-index: 1;
      }
    }
    &-info {
      display: flex;
      align-items: center;
      border-radius: 28rpx;
      margin-top: 19rpx;
      margin-bottom: 23rpx;
      .buttons {
        display: flex;
        justify-content: flex-end;
        align-items: center;
        flex: 1;
        color: #b1b1b1;
        &-item {
          font-size: 26rpx;
          padding: 0 34.884rpx;
          box-sizing: border-box;
          white-space: nowrap;
        }
        &-share {
          color: $dance-main-color;
        }
      }
      &-icon {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 76rpx;
        height: 58rpx;
        border-radius: 20rpx;
        box-sizing: border-box;
      }
    }
    &-navbar {
      margin-left: 23rpx;
    }
    &-name {
      margin: 0 13.953rpx;
      margin-bottom: 10.465rpx;
      padding: 22.674rpx 43.605rpx;
      background-color: #393939;
      &-title {
        position: relative;
        display: flex;
        align-items: center;
        justify-content: space-between;
        .label {
          font-size: 35rpx;
          font-weight: bold;
          margin-right: 47rpx;
          word-break: break-all;
        }
      }
      .subtitle {
        display: flex;
        justify-content: space-between;
        align-items: center;
        .buy {
          color: #959595;
          &-label {
            margin-right: 35rpx;
          }
        }
        .dance {
          padding: 3.488rpx 17.442rpx;
          background-color: #b1b1b1;
          width: fit-content;
          border-radius: 19.186rpx;
          margin-top: 13.953rpx;
          color: #000;
        }
      }
    }
    &-time {
      min-height: 104.651rpx;
      box-sizing: border-box;
      margin: 0 13.953rpx;
      margin-bottom: 66.279rpx;
      padding: 22.674rpx 43.605rpx;
      background-color: #393939;
      display: flex;
      align-items: center;
      &-info {
        height: 100%;
        width: 100%;
        display: flex;
        justify-content: space-between;
        align-items: center;
        font-size: 27.907rpx;
        .time {
          font-family: Source Han Sans CN;
          font-size: 31.395rpx;
          font-weight: 700;
          line-height: 34.884rpx;
        }
      }
    }
    &-tips {
      display: flex;
      min-height: 156.977rpx;
      margin: 0 41.86rpx;
      &-avatar {
        margin-top: 12.209rpx;
        position: relative;
        .add {
          position: absolute;
          width: 29.651rpx;
          height: 29.651rpx;
          border-radius: 50%;
          background-color: #ff7a66;
          position: absolute;
          top: 69.767rpx;
          right: 3.488rpx;
          color: #fff;
          text-align: center;
          font-size: 27.907rpx;
          line-height: 1;
        }
      }
      &-info {
        flex: 1;
        .name {
          color: #d9d9d9;
          font-size: 27.907rpx;
          font-weight: 700;
          margin-top: 3.488rpx;
          display: flex;
          align-items: center;
          &-sub {
            font-size: 24.419rpx;
            color: #b1b1b1;
            margin-left: 34.884rpx;
            font-weight: normal;
          }
        }
        .location {
          margin-top: 34.884rpx;
          color: #959595;
          font-size: 24.419rpx;
          overflow: hidden;
          text-overflow: ellipsis;
          word-break: break-all;
          line-height: 41.86rpx;
        }
      }
      &-icon {
        display: flex;
        align-items: center;
      }
    }
    &-line {
      margin: 0 45.349rpx;
    }
    &-introduce {
      margin: 0 59.302rpx;
      font-size: 24.419rpx;
      color: #959595;
      &-title {
        font-size: 34.884rpx;
        font-weight: 900;
        color: #d9d9d9;
        margin-bottom: 48.837rpx;
      }
      &-grade {
        display: flex;
        .grade {
          width: fit-content;
          background: rgba(97, 71, 178, 1);
          font-size: 19.186rpx;
          font-weight: 900;
          text-align: center;
          color: rgba(255, 255, 255, 1);
          padding: 3px 10.465rpx;
        }
      }
      &-content {
        overflow: hidden;
        text-overflow: ellipsis;
        word-break: break-all;
        display: -webkit-box;
        margin-top: 41.86rpx;
      }
      &-progress {
        margin-top: 33.14rpx;
        font-size: 24.419rpx;
        .progress {
          margin-top: 33.14rpx;
          display: flex;
          .label {
            margin-right: 34.884rpx;
          }
        }
      }
    }
    &-care {
      margin: 0 59.302rpx;
      font-size: 24.419rpx;
      color: #959595;
      &-title {
        font-size: 34.884rpx;
        font-weight: 900;
        color: #d9d9d9;
        margin-bottom: 36.628rpx;
      }
      &-content {
        overflow: hidden;
        text-overflow: ellipsis;
        word-break: break-all;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        line-height: 41.86rpx;
        .item {
          display: flex;
          align-items: flex-start;
          margin-bottom: 8.721rpx;
          line-height: 41.86rpx;
          .yuan {
            margin-right: 20.93rpx;
            width: 17.442rpx;
            height: 17.442rpx;
            border-radius: 50%;
            background-color: #959595;
            flex-shrink: 0;
            margin-top: 1px;
          }
        }
      }
    }
  }
  .video {
    width: 100%;
    height: 100%;
  }

  .float-wrapper {
    position: fixed;
    bottom: 33rpx;
    right: 24rpx;
    display: flex;
    align-items: center;
    flex-direction: row;
    height: 94.186rpx;
    color: #000000a6;
    box-shadow: 0px 1px 10px 0px #0000001a;

    &_txt {
      font-size: 62.791rpx;
      height: 100%;
      font-weight: 900;
      width: 235.465rpx;
      text-align: center;
      color: #fff;
      border-radius: 21rpx 0 0 21rpx;
      background-color: rgba(0, 0, 0, 0.78);
      &-decimal {
        font-weight: 200;
        font-size: 42rpx;
      }
    }
    &_pay {
      height: 100%;
      width: 225rpx;
    }
  }
</style>
